<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">


  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/css/all.min.css" integrity="sha256-mUZM63G8m73Mcidfrv5E+Y61y7a12O5mW4ezU3bxqW4=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/animate.css@3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"example.com","root":"/","images":"/images","scheme":"Muse","darkmode":false,"version":"8.8.1","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":false,"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"}}</script><script src="/js/config.js"></script>
<meta property="og:type" content="website">
<meta property="og:title" content="Maicss">
<meta property="og:url" content="http://example.com/page/2/index.html">
<meta property="og:site_name" content="Maicss">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="Maicss">
<meta name="twitter:card" content="summary">


<link rel="canonical" href="http://example.com/page/2/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":true,"isPost":false,"lang":"zh-CN","comments":"","permalink":"","path":"page/2/index.html","title":""}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>Maicss</title>
  




  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <h1 class="site-title">Maicss</h1>
      <i class="logo-line"></i>
    </a>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu">
        <li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li>
        <li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li>
  </ul>
</nav>




</div>
        
  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>

  <aside class="sidebar">

    <div class="sidebar-inner sidebar-overview-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">Maicss</p>
  <div class="site-description" itemprop="description"></div>
</div>
<div class="site-state-wrap site-overview-item animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">13</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-tags">
        <span class="site-state-item-count">15</span>
        <span class="site-state-item-name">标签</span>
      </div>
  </nav>
</div>



        </div>
      </div>
    </div>
  </aside>
  <div class="sidebar-dimmer"></div>


    </header>

    
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


    <div class="main-inner index posts-expand">

    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/08/29/deepin-wiki/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Maicss">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Maicss">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/08/29/deepin-wiki/" class="post-title-link" itemprop="url">一个中学生搞的wiki</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-08-29 20:36:36" itemprop="dateCreated datePublished" datetime="2021-08-29T20:36:36+08:00">2021-08-29</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2021-11-16 15:49:25" itemprop="dateModified" datetime="2021-11-16T15:49:25+08:00">2021-11-16</time>
      </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p>现在的中学生越来越出乎意料了，以前折腾星火商店的时候，很多都是中学生，个个都身怀绝技，初中就开始搞C++、Qt还同时对音乐、设计颇有研究。不怕大家笑话，这之前我还稍微有一点自负，我感觉计算机这方面我算是入门比较早的了。没想到大佬这么多，还都这么年轻…</p>
<p>前两天有一个深度论坛的老弟由于在论坛吐槽没有wiki无果，居然自己建了一个，只能说佩服。明天就要开始上课了，打算后边有时间慢慢在这个wiki中贡献点内容。wiki的地址是 【<a href="deepin.wiki">deepin.wiki</a>】 希望大家有时间也去参与一下。</p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/08/26/path-env/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Maicss">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Maicss">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/08/26/path-env/" class="post-title-link" itemprop="url">PATH环境变量的介绍</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-08-26 17:14:56" itemprop="dateCreated datePublished" datetime="2021-08-26T17:14:56+08:00">2021-08-26</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2021-11-16 15:49:25" itemprop="dateModified" datetime="2021-11-16T15:49:25+08:00">2021-11-16</time>
      </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p>PATH是一个系统的环境变量，它用法很多人都了解，是指定命令的搜索路径。<br>本例子在Linux下讲解。<br>比如说，在<code>/opt/games/csgo</code>文件夹下有一个名为<code>playcsgo</code>的可执行文件，作用是启动游戏。<br>那么，假如你需要运行它，你必需要输入绝对路径，例如：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">/opt/games/csgo/playcsgo</span><br></pre></td></tr></table></figure>
<p>此时，不出问题的话，游戏已经开始了。<br>但是，路径是很繁长的，每次都要用绝对路径来运行，绝对是个麻烦事。<br>此时PATH环境变量的作用就显现出来了，我希望实现输入<code>playcsgo</code>即可开始游戏，无需前边冗长的路径信息。<br>所以，此时只需要输入以下命令</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># export命令的作用是设置环境变量的值</span></span><br><span class="line"><span class="built_in">export</span> PATH=/opt/games/csgo</span><br></pre></td></tr></table></figure>
<p>先将PATH环境变量的值赋值为对应可执行文件所在的目录，后紧接着输入</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">playcsgo</span><br></pre></td></tr></table></figure>
<p>此时就可以实现省略前边的路径部分了，因为你输入了一个命令，命令就是一个可执行程序，系统会自动在PATH所提供的路径中寻找和你输入命令的名字一致的可执行文件，然后对应执行。</p>
<h2 id="PATH环境变量的通常用法"><a href="#PATH环境变量的通常用法" class="headerlink" title="PATH环境变量的通常用法"></a>PATH环境变量的通常用法</h2><p>其实系统中默认的PATH是有值的，在Linux下，通常包括<code>/usr/bin</code>，那么对Linux不那么熟悉的可以去看一下，平时用的非常频繁的命令，比如<code>cd</code>,<code>mkdir</code>,<code>rm</code>等，都可以在这个目录下找到对应的可执行文件。<br>但是，值得注意的是，PATH中，允许放入多个路径，不仅PATH，其他环境变量也是这样。<br>在Linux操作系统下，不同的值以<code>英文冒号&quot;:&quot;</code>分割，Windows下以<code>英文分号&quot;;&quot;</code>分割。<br>例如：<br>当你输入了上边提到的<code>export PATH=/opt/games/csgo</code>命令后，你将无法使用<code>cd</code>,<code>mkdir</code>等这些命令了，因为你将PATH重新赋值后，其中不再包含<code>/usr/bin</code>,而这些常用命令通常就是在这个目录下，所以会报错显示没有找到命令或可执行文件。<br>那么如何解决?</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 如上所说，两个路径以英文分号隔开</span></span><br><span class="line"><span class="built_in">export</span> PATH=/usr/bin:/opt/games/csgo</span><br></pre></td></tr></table></figure>
<p>但是还是产生了一个问题，假如原来的PATH不止有/usr/bin呢，可能还包含其他路径，比如Java的JDK，此时如果这么做，其他的路径就会失效。<br>所以，下面这个方法，才是最最最正确的用法</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># $PATH表示取的环境变量PATH的值</span></span><br><span class="line"><span class="built_in">export</span> PATH=<span class="variable">$PATH</span>:/opt/games/csgo</span><br></pre></td></tr></table></figure>
<p>这里的意思是追加<code>/opt/games/csgo</code>到PATH原有值的末尾。<br>如图所示：<br><img src="https://z3.ax1x.com/2021/08/26/hnHs6x.png"><br>这时既不影响原有变量的值，还能放心的添加自己想要的路径。</p>
<h2 id="有些问题需要注意一下"><a href="#有些问题需要注意一下" class="headerlink" title="有些问题需要注意一下"></a>有些问题需要注意一下</h2><blockquote>
<p>Q:假如PATH变量中，多个路径有相同名称的可执行文件，那么它要优先选择哪个？<br>A:优先选择路径位于PATH变量靠前的位置的，从上边图中可以看到，PATH变量的储存方式是一串字符串，其中以:隔开，这表示他们是有顺序之分的，系统会优先选择位置靠前的值。</p>
</blockquote>
<blockquote>
<p>Q:在终端中输入上述设置变量的命令，会一直有效吗？<br>A:不会，只在此刻此终端下有效，其他终端无效，并且当你关掉此终端时，你所设置的将丢失；在shell脚本中也是，只在脚本的运行范围内有效。</p>
</blockquote>
<blockquote>
<p>Q:如何设置长期有效的环境变量？<br>A:Windows下很容易，有变量的设置界面，Linux下可以在各种开机自启动脚本中写入设置命令。</p>
</blockquote>
<blockquote>
<p>Q:有些软件需要特定版本的JRE，我怎么让他们所使用的JAVA版本各不相同？<br>A:首先你必须准备所有所需要的版本的JRE，把他们放在不同的文件夹下，然后对每个程序编写运行脚本，shell脚本只在脚本的范围内有效，所以这种方式不会影响到其他程序。<br>脚本内容示例：</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># 假定该程序所需JRE的路径为：/usr/jre8</span></span><br><span class="line"><span class="built_in">export</span> PATH=<span class="variable">$PATH</span>:/usr/jre8/bin <span class="comment">#加bin是因为jre的可执行文件通常在安装目录的bin目录下</span></span><br><span class="line">java playcsgo <span class="comment">#这个命令是执行你想要用上边设置的jre运行的java程序。</span></span><br></pre></td></tr></table></figure>
</blockquote>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




    


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="">
    <link itemprop="mainEntityOfPage" href="http://example.com/2021/08/26/qt-smooth-scroll/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="Maicss">
      <meta itemprop="description" content="">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Maicss">
    </span>
      <header class="post-header">
        <h2 class="post-title" itemprop="name headline">
          <a href="/2021/08/26/qt-smooth-scroll/" class="post-title-link" itemprop="url">Qt列表等控件实现平滑滚动&deepin启动器存在的问题</a>
        </h2>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>

      <time title="创建时间：2021-08-26 17:00:39" itemprop="dateCreated datePublished" datetime="2021-08-26T17:00:39+08:00">2021-08-26</time>
    </span>
      <span class="post-meta-item">
        <span class="post-meta-item-icon">
          <i class="far fa-calendar-check"></i>
        </span>
        <span class="post-meta-item-text">更新于</span>
        <time title="修改时间：2021-11-16 15:49:25" itemprop="dateModified" datetime="2021-11-16T15:49:25+08:00">2021-11-16</time>
      </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
          <p>Qt自带的的列表控件是不能平滑滚动的，但如果滚动速度快的话很容易引起视线丢失，体验效果很差。本篇主要讲述如何在Qt中对列表控件加入平滑滚动。文中以<code>QScrollArea</code>控件为例，其他控件方法一样。</p>
<h2 id="原理"><a href="#原理" class="headerlink" title="原理"></a>原理</h2><p>Qt的列表控件中，有以下两个接口：</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">QAbstractScrollArea::setHorizontalScrollBar</span><span class="params">(QScrollBar *scrollBar)</span></span>;</span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">QAbstractScrollArea::setVerticalScrollBar</span><span class="params">(QScrollBar *scrollBar)</span></span>;</span><br></pre></td></tr></table></figure>

<p>显然上述两个接口的作用是设置控件的横纵两个滚动条，以指针形式传入，我们将以此来实现控制页面的滚动。传入滚动条对象后，我们就可以使用<code>setValue()</code>来间接控制页面的滚动了。然后再使用<code>QPropertyAnimation</code>类来实现滚动的效果。</p>
<h2 id="实现"><a href="#实现" class="headerlink" title="实现"></a>实现</h2><h3 id="一、自定义滚动条控件"><a href="#一、自定义滚动条控件" class="headerlink" title="一、自定义滚动条控件"></a>一、自定义滚动条控件</h3><p>需要实现两个功能：</p>
<ul>
<li>当使用<code>setValue()</code>对滚动条的滑块进行移动时，滑块会在一个时间段内以某种规律连续的移动到目标位置，而不是瞬间移动。</li>
<li>新增一个槽函数<code>void scroll(int value)</code>，实现传入一个数字后相对滚动指定距离。如：scroll(100)就是向下滚动100个单位。</li>
</ul>
<p><strong>头文件：</strong></p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> SMOOTHSCROLLBAR_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SMOOTHSCROLLBAR_H</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;QScrollBar&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;QPropertyAnimation&gt;</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SmoothScrollBar</span> :</span> <span class="keyword">public</span> QScrollBar</span><br><span class="line">&#123;</span><br><span class="line">    Q_OBJECT</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="built_in">SmoothScrollBar</span>(QWidget *parent=<span class="literal">nullptr</span>);</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    <span class="comment">//这里重写鼠标事件的目的是在手动点击或拖动滚动条时更新m_targetValue_v变量，并且在拖动时立即结束滚动的动画。</span></span><br><span class="line">    <span class="comment">//这里如果不明白作用，可以先注释掉看看手动拖动滚动条时对动画有什么影响。</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">mousePressEvent</span><span class="params">(QMouseEvent *)</span> <span class="keyword">override</span></span>;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">mouseReleaseEvent</span><span class="params">(QMouseEvent *)</span> <span class="keyword">override</span></span>;</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">mouseMoveEvent</span><span class="params">(QMouseEvent *)</span> <span class="keyword">override</span></span>;</span><br><span class="line"></span><br><span class="line">    QPropertyAnimation *m_scrollAni; <span class="comment">//用来实现动画</span></span><br><span class="line">    <span class="keyword">int</span> m_targetValue_v; <span class="comment">//用来记录目标位置的变量</span></span><br><span class="line"><span class="keyword">public</span> slots:</span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">setValue</span><span class="params">(<span class="keyword">int</span> value)</span></span>; <span class="comment">//重写的setValue槽函数，实现动画效果</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">scroll</span><span class="params">(<span class="keyword">int</span> value)</span></span>; <span class="comment">//新增相对滚动的槽函数，value为滚动距离的矢量表示</span></span><br><span class="line">signals:</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span> <span class="comment">// SMOOTHSCROLLBAR_H</span></span></span><br></pre></td></tr></table></figure>

<p><strong>源文件：</strong></p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;smoothscrollbar.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;QWheelEvent&gt;</span></span></span><br><span class="line">SmoothScrollBar::<span class="built_in">SmoothScrollBar</span>(QWidget* parent):<span class="built_in">QScrollBar</span>(parent)</span><br><span class="line">&#123;</span><br><span class="line">    m_scrollAni=<span class="keyword">new</span> QPropertyAnimation;</span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">setTargetObject</span>(<span class="keyword">this</span>);</span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">setPropertyName</span>(<span class="string">&quot;value&quot;</span>);</span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">setEasingCurve</span>(QEasingCurve::OutQuint); <span class="comment">//设置动画曲线，在Qt文档中有详细的介绍</span></span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">setDuration</span>(<span class="number">800</span>); <span class="comment">//设置动画时间，数值越小播放越快</span></span><br><span class="line">    m_targetValue_v=<span class="built_in">value</span>(); <span class="comment">//将m_targetValue_v初始化</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">SmoothScrollBar::setValue</span><span class="params">(<span class="keyword">int</span> value)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">stop</span>();<span class="comment">//停止现在的动画，防止出现冲突</span></span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">setStartValue</span>(<span class="keyword">this</span>-&gt;<span class="built_in">value</span>()); <span class="comment">//设置动画滚动的初始值为当前位置</span></span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">setEndValue</span>(value); <span class="comment">//设置动画的结束位置为目标值</span></span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">start</span>(); <span class="comment">//开始动画</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">SmoothScrollBar::scroll</span><span class="params">(<span class="keyword">int</span> value)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">//这里推荐评论区中大佬优化的写法</span></span><br><span class="line">    m_targetValue_v-=value; <span class="comment">//将目标值和相对位置进行运算</span></span><br><span class="line">    <span class="built_in">setValue</span>(m_targetValue_v); <span class="comment">//开始动画</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">SmoothScrollBar::mousePressEvent</span><span class="params">(QMouseEvent *e)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">//当使用鼠标操作滚动条时，不会刷新m_targetValue_v的值，因而需要重写事件，对其进行刷新。</span></span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">stop</span>();</span><br><span class="line">    QScrollBar::<span class="built_in">mousePressEvent</span>(e);</span><br><span class="line">    m_targetValue_v=<span class="built_in">value</span>();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">SmoothScrollBar::mouseReleaseEvent</span><span class="params">(QMouseEvent *e)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">stop</span>();</span><br><span class="line">    QScrollBar::<span class="built_in">mouseReleaseEvent</span>(e);</span><br><span class="line">    m_targetValue_v=<span class="built_in">value</span>();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">SmoothScrollBar::mouseMoveEvent</span><span class="params">(QMouseEvent *e)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">stop</span>();</span><br><span class="line">    QScrollBar::<span class="built_in">mouseMoveEvent</span>(e);</span><br><span class="line">    m_targetValue_v=<span class="built_in">value</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>



<h3 id="二、自定义列表控件"><a href="#二、自定义列表控件" class="headerlink" title="二、自定义列表控件"></a>二、自定义列表控件</h3><p>将列表的滚动条替换为我们刚刚自定义的滚动条</p>
<p><strong>头文件：</strong></p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">ifndef</span> SMOOTHSCROLLAREA_H</span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">define</span> SMOOTHSCROLLAREA_H</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;QWidget&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;QScrollArea&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;smoothscrollbar.h&quot;</span></span></span><br><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">SmoothScrollArea</span> :</span> <span class="keyword">public</span> QScrollArea</span><br><span class="line">&#123;</span><br><span class="line">    Q_OBJECT</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line">    <span class="function"><span class="keyword">explicit</span> <span class="title">SmoothScrollArea</span><span class="params">(QWidget *parent = <span class="literal">nullptr</span>)</span></span>;</span><br><span class="line"><span class="keyword">private</span>:</span><br><span class="line">    SmoothScrollBar* vScrollBar; <span class="comment">//纵向滚动条</span></span><br><span class="line">    <span class="function"><span class="keyword">void</span> <span class="title">wheelEvent</span><span class="params">(QWheelEvent* e)</span></span>; <span class="comment">//捕获鼠标滚轮事件</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="meta-keyword">endif</span> <span class="comment">// SMOOTHSCROLLAREA_H</span></span></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<p><strong>源文件：</strong></p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&quot;smoothScrollArea.h&quot;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;QVBoxLayout&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;QLabel&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;QWheelEvent&gt;</span></span></span><br><span class="line"><span class="meta">#<span class="meta-keyword">include</span> <span class="meta-string">&lt;QDebug&gt;</span></span></span><br><span class="line">SmoothScrollArea::<span class="built_in">SmoothScrollArea</span>(QWidget *parent) : <span class="built_in">QScrollArea</span>(parent)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">auto</span> layout = <span class="keyword">new</span> QVBoxLayout;</span><br><span class="line">    vScrollBar=<span class="keyword">new</span> <span class="built_in">SmoothScrollBar</span>();</span><br><span class="line">    vScrollBar-&gt;<span class="built_in">setOrientation</span>(Qt::Orientation::Vertical); <span class="comment">//将滚动条设置为纵向</span></span><br><span class="line">    QWidget* w=<span class="keyword">new</span> QWidget; <span class="comment">//主体Widget</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">int</span> i=<span class="number">0</span>;i&lt;<span class="number">200</span> ;i++ ) &#123; <span class="comment">//在w中加入200个label，用来测试滚动</span></span><br><span class="line">        QFont font;</span><br><span class="line">        font.<span class="built_in">setPointSize</span>(i+<span class="number">1</span>);</span><br><span class="line">        <span class="keyword">auto</span> a=<span class="keyword">new</span> <span class="built_in">QLabel</span>(QString::<span class="built_in">number</span>(i));</span><br><span class="line">        a-&gt;<span class="built_in">setFont</span>(font);</span><br><span class="line">        layout-&gt;<span class="built_in">addWidget</span>(a);</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="built_in">setVerticalScrollBar</span>(vScrollBar); <span class="comment">//设置纵向滚动条</span></span><br><span class="line">    w-&gt;<span class="built_in">setLayout</span>(layout); <span class="comment">//设置布局</span></span><br><span class="line">    <span class="built_in">setWidget</span>(w); <span class="comment">//设置widget</span></span><br><span class="line"></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">SmoothScrollArea::wheelEvent</span><span class="params">(QWheelEvent *e)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="comment">//当捕获到事件后，调用相对滚动的槽函数</span></span><br><span class="line">    vScrollBar-&gt;<span class="built_in">scroll</span>(e-&gt;<span class="built_in">angleDelta</span>().<span class="built_in">y</span>());</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>到此为止，<code>SmoothScrollArea</code>类便可以支持纵向的平滑滚动。其他的列表控件方法一致。</p>
<h3 id="三、测试效果"><a href="#三、测试效果" class="headerlink" title="三、测试效果"></a>三、测试效果</h3><p>将<code>SmoothScrollArea</code>列表控件加入到主窗口后，运行即可。</p>
<h2 id="补充"><a href="#补充" class="headerlink" title="补充"></a>补充</h2><p>在此之前参考过<code>deepin-launcher</code>的小窗口模式列表代码，deepin的平滑滚动策略存在缺陷，导致体验较差。这里我详细说明一下这一简单的问题，非deepin用户或开发者可以到此为止了。</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * @brief AppListView::wheelEvent 鼠标滑轮事件触发滑动区域控件动画</span></span><br><span class="line"><span class="comment"> * @param e 鼠标滑轮事件指针对象</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">void</span> <span class="title">AppListView::wheelEvent</span><span class="params">(QWheelEvent *e)</span></span></span><br><span class="line"><span class="function"></span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (e-&gt;<span class="built_in">orientation</span>() == Qt::Horizontal)</span><br><span class="line">        <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">int</span> offset = -e-&gt;<span class="built_in">delta</span>();</span><br><span class="line"></span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">stop</span>();</span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">setStartValue</span>(<span class="built_in">verticalScrollBar</span>()-&gt;<span class="built_in">value</span>());</span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">setEndValue</span>(<span class="built_in">verticalScrollBar</span>()-&gt;<span class="built_in">value</span>() + offset * m_speedTime);</span><br><span class="line">    m_scrollAni-&gt;<span class="built_in">start</span>();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>由代码中可以看到，首先他屏蔽了横向滑动的事件，这个主要应对触控板的一些问题。</p>
<p><code>offset</code>为滚动的距离，每次滚动之前先停止上次动画（如果还没有结束的话），然后在以当前位置为起始位置，以相对offset的位置为结束位置，这就会导致一个问题。</p>
<p>假设有两个连续的滚动事件被触发，上边这个函数就会执行两次。这里会出现两种情况：</p>
<ul>
<li>两次连续的事件时间间隔比较大，鼠标滚轮速度比较慢。</li>
<li>两次连续事件时间间隔很小，小于动画时长，鼠标滚动速度很快。</li>
</ul>
<p>第一种情况下，deepin的这个方案并没有什么问题，两次动画之间互不干扰。但是第二种情况就会发现问题，假设动画时长为800ms，当第一次滚动事件触发后，随后800ms的时间中，滚动条将相应的向目标位置滚动，但是当第二次事件在第一次的动画还未结束时到来的话，第一次的动画将被打断，也就是只滚动了一部分就结束了，因此，当连续的快速滚动事件结束后，实际滚动的距离要远小于期望的距离。</p>
<p>这个问题在本文中的解决方案时建立一个目标位置的变量。此变量用于记录滚动所期望的位置，不会导致滚动失真。</p>
<p><strong>大致如下：</strong></p>
<p>设记录目标位置的变量为<code>a</code>，a的值将被初始化为滚动条当前的value，此后，当鼠标滚动事件被触发时，首先将a的值通过和滚动距离的计算变为新的位置，此时当前位置与a的值将不再相等，然后在通过动画将结束位置定为a。这样处理的好处，通过上边的方法分析如下：</p>
<p>首先第一种情况是没有区别的，来看第二种。同样假设动画时方案长为800ms，当第一次滚动事件发生后，a将被计算为要滚动的目标位置，随后的800ms将是动画的执行过程，当这个过程还未结束时，第二次滚动又将a的值通过和滚动距离的计算，变为一个新的位置，再由动画去执行。这里注意，a在两次变化中，第一次的距离并未丢失，两次距离相加，当连续的快速滚动事件结束后，实际滚动的距离等于所期望的距离。</p>
<p><strong>deepin那种方案所导致的现象</strong></p>
<ul>
<li>快速滚动滚轮并不能让列表的滚动速度便快，甚至还可能不如滚轮滚的慢一点。</li>
<li>滚动的动画将会在一些情况下看起来不流畅</li>
</ul>
<p>希望deepin能采纳文中的方案。<br>文中代码下载地址：<a target="_blank" rel="noopener" href="https://maicss.lanzoui.com/iQHCHswqm6j">https://maicss.lanzoui.com/iQHCHswqm6j</a></p>

      
    </div>

    
    
    

    <footer class="post-footer">
        <div class="post-eof"></div>
      
    </footer>
  </article>
</div>




  <nav class="pagination">
    <a class="extend prev" rel="prev" href="/"><i class="fa fa-angle-left" aria-label="上一页"></i></a><a class="page-number" href="/">1</a><span class="page-number current">2</span>
  </nav>

</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Maicss</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <script src="https://cdn.jsdelivr.net/npm/animejs@3.2.1/lib/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script>

  





  





</body>
</html>
